/*
 * DatabaseListResource.java
 *
 * Created on November 23, 2007, 4:03 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package org.atomojo.app.admin;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import org.atomojo.app.AtomApplication;
import org.atomojo.app.Storage;
import org.atomojo.app.StorageFactory;
import org.atomojo.app.client.XMLRepresentationParser;
import org.atomojo.app.db.DB;
import org.atomojo.app.db.DBInfo;
import org.infoset.xml.Document;
import org.infoset.xml.Element;
import org.infoset.xml.XMLException;
import org.infoset.xml.util.DocumentDestination;
import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.resource.ServerResource;

/**
 *
 * @author alex
 */
public class AllDatabaseBackupResource extends ServerResource
{
   
   /** Creates a new instance of SyncResource */
   public AllDatabaseBackupResource() {
      setNegotiated(false);
   }
   
   public Representation get()
   {
      getResponse().setStatus(Status.SUCCESS_NO_CONTENT);
      return null;
   }
   
   public Representation post(Representation entity)
   {
      if (!XMLRepresentationParser.isXML(entity.getMediaType())) {
         getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
         return new StringRepresentation("Non-XML media type for entity body: "+entity.getMediaType().getName());
      }
      
      Map<String,DBInfo> dbList = (Map<String,DBInfo>)getContext().getAttributes().get(DatabaseListResource.DB_LIST);
      Map<String,DBInfo> autodbList = (Map<String,DBInfo>)getContext().getAttributes().get(DatabaseListResource.AUTO_DB_LIST);
      StorageFactory storageFactory = (StorageFactory)getContext().getAttributes().get(DatabaseListResource.STORAGE_FACTORY);
      XMLRepresentationParser parser = new XMLRepresentationParser();
      try {
         DocumentDestination dest = new DocumentDestination();
         
         parser.parse(entity,AdminApplication.createAdminDocumentDestination(dest,AdminXML.NM_BACKUP));
         Document doc = dest.getDocument();
         
         Element top = doc.getDocumentElement();
         String location = top.getAttributeValue("location");
         if (location==null) {
            getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
            return new StringRepresentation("The 'location' attribute is missing.");
         }
         location = location.trim();
         if (location.length()==0) {
            getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
            return new StringRepresentation("The 'location' attribute is empty.");
         }
         File dir = new File(location);
         if (!dir.exists()) {
            if (!dir.mkdirs()) {
               getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
               return new StringRepresentation("The "+dir.getAbsolutePath()+" doesn't exist and can't be created.");
            }
         }
         if (!dir.canWrite()) {
            getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
            return new StringRepresentation("Cannot write to "+dir.getAbsolutePath());
         }
         
         Set<String> dbNames = new TreeSet<String>();
         Iterator<Element> names = top.getElementsByName(AdminXML.NM_NAME);
         while (names.hasNext()) {
            dbNames.add(names.next().getText());
         }

         List<Map<String,DBInfo>> lists = new ArrayList<Map<String,DBInfo>>();
         lists.add(dbList);
         lists.add(autodbList);
         
         boolean ok = true;
         for (Map<String,DBInfo> map : lists) {
            for (DBInfo dbinfo : map.values()) {
               DB db = dbinfo.getDB();
               if (dbNames.size()>0 && !dbNames.contains(db.getName())) {
                  continue;
               }
               try {
                  Storage storage = storageFactory.getStorage(db);
                  Backup backup = new Backup(db,storage,AtomApplication.RESOURCE_BASE);
                  File zipFile = new File(dir,db.getName()+".zip");
                  backup.toZip(db.getName(), zipFile);
               } catch (Exception ex) {
                  getLogger().log(Level.SEVERE,"Cannot backup database "+db.getName()+" due to exception.",ex);
                  ok = false;
               }
            }
         }
         
         getResponse().setStatus(ok ? Status.SUCCESS_CREATED : Status.SERVER_ERROR_INTERNAL);
         return null;
         
      } catch (IOException ex) {
         getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
         return new StringRepresentation("I/O exception: "+ex.getMessage());
      } catch (XMLException ex) {
         getResponse().setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
         return new StringRepresentation("XML exception: "+ex.getMessage());
      }
   }
}
